#if !defined(_weight_set_operator_test_)
#define _weight_set_operator_test_

#include <src/math/Operators/weight_set_operator.h>
#include <src/math/BoundaryCondition/BoundaryCondition.h>


template <class data, std::size_t Dim = data::Dim> 
struct weight_set_fill_data  
{
	data operator()(std::size_t i)
	{
		OS_STATIC_CHECK(false); // you have to implement this test
	};
};

template <class data> 
struct weight_set_fill_data<data,1>
{
	enum {dim = 3};
	data operator()()
	{
		data A(dim);
		for (OS_int i = 0; i<dim;++i) {
			A[i] = i+1;
		};
		return A;
	};
};

template <class data> 
struct weight_set_fill_data<data,2> 
{
	enum {dim1 = 3,dim2 = 3};
	data operator()() 
	{
		data A(dim1,dim2);
		for (OS_int i = 0; i<dim1;++i) {
			for (OS_int j = 0; j<dim2;++j)
				A[i][j] = i+j;
		};
		return A;
	};
};


template <class weighted_operator_type>
void weight_set_operator_example(){
	typedef weighted_operator_type::weight_set_type matrix_type;
	typedef weighted_operator_type::argument_base_type argument_base_type;

	std::cout << std::endl << "----Start weight_set_operator_example---------------------" << std::endl ;
	std::cout << std::endl << " example for class " << typeid(weighted_operator_type).name()<< std::endl << std::endl ;

	weighted_operator_identity<argument_base_type> id(3);
	argument_base_type un = weight_set_fill_data<argument_base_type>()();
	std::cout << "A vector " << un << std::endl;
	std::cout << "Identity Operator Id" << id ;
	weighted_operator_type::weight_set_type Id_Matrix(3,3,3);
	for (std::size_t i = 0; i < 3;++i)
		Id_Matrix(i,i) = 1;
	std::cout << "Identity Matrix Id" << Id_Matrix << std::endl<< std::endl;

	std::cout << "Testing Algebra ..." << std::endl;

	weighted_operator_type operator1(Id_Matrix) ;
	weighted_operator_type operator2;
	operator2 = operator1;
	bool result = operator2 == operator1;
	OS_DYNAMIC_CHECK(result == true, "weight_set_operator_example : test operator2 == operator1 failed");


	OS_DYNAMIC_CHECK(operator1 == id, "weight_set_operator_example : test operator1 != id failed");
	argument_base_type un_1 = operator1(un);
	std::cout << "Identity applied to vector : " << un_1;
	OS_DYNAMIC_CHECK(un_1 == un, "weight_set_operator_example : test un_1 == un failed");

	operator2 = id/2.;
	un_1 = operator2(un);
	OS_DYNAMIC_CHECK(un_1 == un/2., "weight_set_operator_example : test un_1 == un/2. failed");
	operator2 = id+operator1;
	un_1 = operator2(un);
	OS_DYNAMIC_CHECK(un_1 == un*2., "weight_set_operator_example : test un_1 == un*2. failed");
	operator2 = id-operator1;
	un_1 = operator2(un);
	OS_DYNAMIC_CHECK(un_1 == 0.*un, "weight_set_operator_example : test un_1 == 0. failed");
	operator2 = 2.*(3.*id+id/2.);
	un_1 = operator2(un);
	OS_DYNAMIC_CHECK(un_1 == 7.*un, "weight_set_operator_example : test un_1 == 7.*un failed");
	std::cout << "Output Operator 2.*(3.*Id+Id/2.) : " << std::endl<< operator2 << std::endl;
	weighted_operator_type operator3;
	operator3 = operator2;
	result = operator3 == operator2;
	OS_DYNAMIC_CHECK(result == true, "weight_set_operator_example : test operator3 == operator2 failed");
	std::cout << std::endl << "----End weight_set_operator_example---------------------" << std::endl ;

};

void weight_set_operator_test();


#endif